/*
 * Tencent is pleased to support the open source community by making
 * MMKV available.
 *
 * Copyright (C) 2018 THL A29 Limited, a Tencent company.
 * All rights reserved.
 *
 * Licensed under the BSD 3-Clause License (the "License"); you may not use
 * this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *       https://opensource.org/licenses/BSD-3-Clause
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.tencent.mmkv;


import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.aafwk.ability.RunningProcessInfo;
import ohos.app.Context;
import ohos.app.IAbilityManager;
import ohos.bundle.AbilityInfo;
import ohos.bundle.IBundleManager;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.utils.PacMap;
import ohos.utils.net.Uri;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class MMKVContentProvider extends Ability {

    static protected final String KEY = "KEY";
    static protected final String KEY_SIZE = "KEY_SIZE";
    static protected final String KEY_MODE = "KEY_MODE";
    static protected final String KEY_CRYPT = "KEY_CRYPT";
    static protected final String FUNCTION_NAME = "mmkvFromAshmemID";

    static private Uri gUri;
    @Nullable
    static protected Uri contentUri(Context context) {
        if (MMKVContentProvider.gUri != null) {
            return MMKVContentProvider.gUri;
        }
        if (context == null) {
            return null;
        }
        String authority = queryAuthority(context);
        if (authority == null) {
            return null;
        }
        MMKVContentProvider.gUri = Uri.parse("dataability" + "://" + authority);
        return MMKVContentProvider.gUri;
    }

    private PacMap mmkvFromAshmemID(String ashmemID, int size, int mode, String cryptKey) throws DataAbilityRemoteException {
        MMKV mmkv = MMKV.mmkvWithAshmemID( getApplicationContext(),ashmemID, size, mode, cryptKey);
        if (mmkv != null) {
            ParcelableMMKV parcelableMMKV = new ParcelableMMKV(mmkv);
            HiLog.info(new HiLogLabel(HiLog.INFO,300,null),"MMKV", ashmemID + " fd = " + mmkv.ashmemFD() + ", meta fd = " + mmkv.ashmemMetaFD());
            PacMap result = new PacMap();
            result.putSequenceableObject(MMKVContentProvider.KEY, parcelableMMKV);
            return result;
        }
        return null;
    }

    private static String queryAuthority(Context context) {
        try {
            IBundleManager mgr = context.getBundleManager();
            if (mgr != null) {
                AbilityInfo providerInfo =context.getAbilityInfo();
                if (providerInfo != null) {
                    return providerInfo.label;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

//    @Override
//    public boolean onCreate() {
//        Context context = getContext();
//        if (context == null) {
//            return false;
//        }
//        String authority = queryAuthority(context);
//        if (authority == null) {
//            return false;
//        }
//
//        if (MMKVContentProvider.gUri == null) {
//            MMKVContentProvider.gUri = Uri.parse("content" + "://" + authority);
//        }
//
//        return true;
//    }

    protected static String getProcessNameByPID(Context context, int pid) {
        IAbilityManager manager = (IAbilityManager) context.getAbilityManager();
        if (manager != null) {
            // clang-format off
            for (RunningProcessInfo processInfo
                    : manager.getAllRunningProcesses()) {
                if (processInfo.getPid() == pid) {
                    return processInfo.getProcessName();
                }
            }
            // clang-format on
        }
        return "";
    }

    @Nullable
    public PacMap call(@NotNull String method, @NotNull String mmapID, @NotNull PacMap extras) {
        if (method.equals(MMKVContentProvider.FUNCTION_NAME)) {
            if (extras != null) {
                int size = extras.getIntValue(MMKVContentProvider.KEY_SIZE);
                int mode = extras.getIntValue(MMKVContentProvider.KEY_MODE);
                String cryptKey = extras.getString(MMKVContentProvider.KEY_CRYPT);
                try {
                    return mmkvFromAshmemID(mmapID, size, mode, cryptKey);
                } catch (DataAbilityRemoteException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }


}
